﻿namespace Beetle.Clients
{
    using Beetle;
    using System;
    using System.Collections.Generic;
    using System.Configuration;

    public class TcpAsnyPool
    {
        private Dictionary<string, TcpAsynNode> _field_a;
        private Action<TcpChannel> _field_b;
        private List<TcpAsynNode> _field_c;
        [ThreadStatic]
        private static TcpAsnyPool_a _field_d;
        [ThreadStatic]
        private static object _field_e;

        public TcpAsnyPool(Action<TcpChannel> oncreate)
        {
            this._field_a = new Dictionary<string, TcpAsynNode>(0x10);
            this._field_c = new List<TcpAsynNode>();
            this._field_b = oncreate;
        }

        public TcpAsnyPool(string section, Action<TcpChannel> oncreate)
        {
            this._field_a = new Dictionary<string, TcpAsynNode>(0x10);
            this._field_c = new List<TcpAsynNode>();
            this._field_b = oncreate;
            PoolSection section2 = (PoolSection) ConfigurationManager.GetSection(section);
            if (section2 == null)
            {
                throw NetTcpException.ClientPoolSectionNotFound(section);
            }
            if (section != null)
            {
                foreach (ServerNode node in section2.Servers)
                {
                    this.AddNode(node.Name, node.Host, node.Port, node.MaxConnections, node.DetectTime);
                }
            }
        }

        public void AddNode(string name, string host, int port, int maxconnections)
        {
            this.AddNode(name, host, port, maxconnections, 30);
        }

        public void AddNode(string name, string host, int port, int maxconnections, int detectTime)
        {
            TcpAsynNode item = new TcpAsynNode(host, port, maxconnections, this._field_b) {
                Name = name,
                DetectTime = detectTime
            };
            this.Nodes.Add(item);
            this._field_a.Add(name, item);
        }

        public void Connect()
        {
            foreach (TcpAsynNode node in this.Nodes)
            {
                node.Connect();
            }
        }

        public virtual TcpAsynNode GetNode()
        {
            if (_field_d == null)
            {
                _field_d = new TcpAsnyPool_a();
            }
            if (this._field_c.Count != 0)
            {
                int num = 0;
                TcpAsynNode node = null;
                while (num <= this._field_c.Count)
                {
                    _field_d._field_a++;
                    if (_field_d._field_a >= this._field_c.Count)
                    {
                        _field_d._field_a = 0;
                    }
                    node = this._field_c[_field_d._field_a];
                    if (node.Status == NodeStatus.Error)
                    {
                        node.CheckState();
                    }
                    else
                    {
                        return node;
                    }
                    num++;
                }
            }
            return null;
        }

        public virtual TcpAsynNode GetNode(params string[] names)
        {
            TcpAsynNode node = null;
            for (int i = 0; i < names.Length; i++)
            {
                if (this._field_a.TryGetValue(names[i], out node))
                {
                    if (node.Status != NodeStatus.Error)
                    {
                        return node;
                    }
                    node.CheckState();
                }
            }
            return null;
        }

        public bool Send(object message)
        {
            TcpAsynNode node = this.GetNode();
            if ((node == null) || (node.Status == NodeStatus.Error))
            {
                throw NetTcpException.ConnectionIsNotAvailable();
            }
            return node.Send(message);
        }

        public bool Send(object message, params string[] nodes)
        {
            TcpAsynNode node = this.GetNode(nodes);
            if ((node == null) || (node.Status == NodeStatus.Error))
            {
                throw NetTcpException.ConnectionIsNotAvailable();
            }
            return node.Send(message);
        }

        public IList<TcpAsynNode> Nodes
        {
            get
            {
                return this._field_c;
            }
        }

        public static object UserToken
        {
            get
            {
                return _field_e;
            }
            set
            {
                _field_e = value;
            }
        }

        private class TcpAsnyPool_a
        {
            public int _field_a;
        }
    }
}

